﻿using GRPCClass;
using SdtpsBase;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace SdtpsNodeLibrary
{
    public class TaskRun
    {
        public static System.Runtime.Caching.MemoryCache Cache_WFPWorkTablePlug = new System.Runtime.Caching.MemoryCache("WFPWorkTableSpecialPlug");
        /// <summary>
        /// 执行插件
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static GRPCClass.TaskReply ExecutePlug(GRPCClass.TaskRequest value)
        {
            GRPCClass.TaskReply tr = null;
            DataRow mydr=null;
            ITaskEngine myte = null;
            try
            {
                mydr = FindPlug(value.TaskType);
            }
            catch (Exception cw)
            {
                tr = new GRPCClass.TaskReply();
                tr.TaskInfo = value;
                tr.ID = value.ID;
                tr.Message = string.Format("获取配置文件异常:{0}\r\n{1}", cw.Message, cw.StackTrace);
                tr.TaskInfo.EndTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
                return tr;
            }
            if (mydr == null)
            {
                return new GRPCClass.TaskReply()
                {
                    ErrorMessage = string.Format("任务类型{0}不支持", value.TaskType)
                ,
                    TaskInfo = value
                ,
                    ID = value.ID
                ,
                    Status = 3
                };
            }
           
      
            try
            {
                myte = getEngine(mydr);
                myte.TaskFinish += new EventHandler(Task_Finish);
            }
            catch (Exception cw)
            {
                tr = new GRPCClass.TaskReply();
                tr.TaskInfo = value;
                tr.ID = value.ID;
                tr.Message = string.Format("初始化任务执行对象异常:{0}\r\n{1}", cw.Message, cw.StackTrace);
                tr.TaskInfo.EndTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");

            }
            if (myte != null)
            {
                try
                {
                    tr = myte.execture(value);
                    return tr;
                }
                catch (Exception cw)
                {
                    tr = new GRPCClass.TaskReply();
                    tr.TaskInfo = value;
                    tr.ID = value.ID;
                    tr.Message = string.Format("执行任务异常:{0}\r\n{1}", cw.Message, cw.StackTrace);
                    tr.TaskInfo.EndTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
                }
            }
            Task_End(value, tr);
            return tr;
        }
        /// <summary>
        /// 移除队列
        /// </summary>
        /// <param name="trvalue"></param>
        /// <param name="tpvalue"></param>
        public static TaskReply Task_End(TaskRequest trvalue,TaskReply tpvalue)
        {
            GRPCClass.TaskReply tr;
            if (tpvalue != null)
            {
                tr = tpvalue;
                tpvalue.Status = 2;
                tpvalue.TaskInfo.EndTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); 
            }
            else
            {
                tr = new GRPCClass.TaskReply();
                tr.TaskInfo = trvalue;
                tr.Status = 2;
                tr.TaskInfo.EndTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); 
            }
            tr.NodeWorkID = NodeHandle.AppWorker.ID;

            //从执行列表中删除
            TaskNodeHandle.taskReplyRuning.Remove(trvalue);
            //回复中心节点
            TaskNodeHandle.ReplyNode(tpvalue);
            return tr;
        }

        /// <summary>
        /// 任务结束后执行的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public static void Task_Finish(object sender, EventArgs e)
        {
            ITaskEngine myte = (ITaskEngine)sender;
            TaskRequest trvalue = myte.taskrequest;
            TaskReply tpvalue = myte.taskteply;

            ///执行后回复中心节点
            myte.taskteply = Task_End(trvalue, tpvalue);
             
        }
        private static object objlock = new object();
        private static ITaskEngine getEngine(DataRow mydr)
        {
            string filename = mydr["dllname"].ToString();
            string classname = mydr["classname"].ToString();
            Boolean singleton=false;
            try
            {
                singleton = (Boolean)mydr["singleton"];
            }
            catch  
            {
                singleton = true;
            }
            string tasktype = mydr["tasktype"].ToString(); ;
            ITaskEngine myte;
            if (singleton)
            {
                myte = Cache_WFPWorkTablePlug.Get(tasktype) as ITaskEngine;
                if (myte != null)
                {
                    return myte;
                }
            }
            myte = getEngine(filename, classname);
            if (singleton && myte != null)
            {
                Cache_WFPWorkTablePlug.Set(tasktype, myte, null);
            }
            return myte;
        }
        private static ITaskEngine getEngine(string filename, string classname)
        {
            Assembly vAssembly;
            if (string.IsNullOrEmpty(filename))
            {
                vAssembly = Assembly.GetExecutingAssembly();
            }
            else
            {
                string fullname = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, filename);
                if (!File.Exists(fullname))
                {
                    throw new Exception("错误：相关插件文件不存在\r\n" + filename);
                }

                byte[] bin = null;
                lock (objlock)
                {
                    File.SetAttributes(filename, FileAttributes.Archive);
                    using (FileStream fs = new FileStream(filename, FileMode.Open))
                    {
                        using (BinaryReader br = new BinaryReader(fs))
                        {
                            bin = br.ReadBytes(Convert.ToInt32(fs.Length));
                            fs.Close();
                            br.Close();
                            fs.Dispose();
                        }
                    }
                }
                vAssembly = Assembly.Load(bin);// Assembly.LoadFrom(filename);
            }
            System.Globalization.CultureInfo gcnull = null;
            object[] objnull = null;
            Binder binull = null;
            object vTemp = null;
            object[] objParm = null;//传递的参数
            vTemp = vAssembly.CreateInstance(classname, true, BindingFlags.Default, binull, objParm, gcnull, objnull);
            if (vTemp != null)
            {
                ITaskEngine ie = vTemp as ITaskEngine;
                return ie;
            }
            return null;
        }
        private static DataSet mydsplug;
        public static DataRow FindPlug(string tasktype)
        {
            string filename = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "sdtpstask.config");
            if (!System.IO.File.Exists(filename))
            {
                throw new Exception(string.Format("必要的配置文件不存在\r\n{0}",filename));
            }
            mydsplug = new DataSet("taksconfig");
            mydsplug.ReadXml(filename);
            DataRow[] finddr = mydsplug.Tables[0].Select(string.Format("tasktype='{0}' and enable=1", tasktype));
            if (finddr.Length > 0)
            {
                return finddr[0];
            }
            return null;
        }
    }
}
